home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Extravaganza - Disc 1
/
ShareWare Extravaganza 1 of 4 (The Ultimate Shareware Company).iso
/
sblaster
/
lrgsnded.zip
/
LRGSNDED.C
next >
Wrap
C/C++ Source or Header
|
1990-06-01
|
13KB
|
497 lines
/*============================================================================
* File : LRGSNDED.C *
* Title : Sound Editor for buffers larger than 64K *
* *
* Author : Randall Smith, Dept. of Classics, UCSB *
* Project : COVOX Sound Digitizing *
* System : Microsoft C 6.0 *
* Microsoft Quick C 2.51 *
* *
* Ver DDMmmYY Name Comment *
* --- ------- ---- ------- *
* 1.0 30May90 Randall Smith Original version of SEDIT.C *
* 2.0 31May90 Randall Smith Removed item editing to make general version *
* 2.1 01Jun90 Randall Smith Cleaned up a few details and added keyboard *
* *
* *
* Copyright (c) Randall M. Smith 1990 *
* --------- *
* This source code may be used freely as long as its origin is acknowledged.*
* *
* *
* Summary *
* ------- *
* This provides a sound file recording, viewing, and playback function. *
* It requires a VGA and works best with a mouse. It is currently hard wired*
* to use 4 blocks of 64000 bytes each and will crash if that much free RAM *
* is not available. It relies on the compiler correctly working with HUGE *
* arrays, which the COVOX library routines were not designed for, so it may *
* not work in every type of system and memory configuration. *
* *
*==========================================================================*/
#include "snddefs.h"
#include "say8.h"
#include "rec8.h"
#define NUM_BUTTONS 7
#define L_BUT 0
#define PLAY 1
#define ZOOM 2
#define RECRD 3
#define LOAD 4
#define QUIT 5
#define R_BUT 6
#define WIDTH 90
#define BLK 64000
#define BUFFSIZE 4 * BLK
#define RECORD_SIZE 256L
char *button_text[] = {
"< <== >",
"<play>",
"<zoom>",
"<recrd>",
" <load>",
"<quit>",
"< ==> >"
};
int block, section;
unsigned int mpx;
BOOL zoom_flag, mse_flag;
FILE *out_fp;
static long count = 0;
main(int argc, char *argv[])
{
int stream, i;
int rate, port_out, treble, ret;
unsigned int segbuf, num_read, j;
unsigned int num_to_write;
char in_fname[_MAX_PATH], out_fname[_MAX_PATH], tmp_num[10], tmp_msg[80];
BYTE huge *temp_buffer = NULL;
BYTE huge *say_buffer = NULL;
long filesize, size, templong, left_cursor, right_cursor;
BOOL quit_flag;
BYTE tmp_chr;
ret = check_mouse(); /* see if mouse is present, and if not do not try to use it */
if (ret == NO_MOUSE) {
mse_flag = FALSE;
}
else {
mse_flag = TRUE;
}
limit_cursor(HORIZ, 0, 640); /* set cursor field to full VGA screen */
limit_cursor(VERT, 0, 480);
/* set default conditions. Change these for different systems. */
rate = 132;
port_out = 4;
treble = 0;
left_cursor = 0L;
right_cursor = 64000L;
mpx = 100;
out_fname[0] = '\0';
in_fname[0] = '\0';
init_screen();
if( _dos_allocmem( (BUFFSIZE/16)+2, &segbuf ) ) {
get_string("Not enough memory for data. Press any key...", tmp_msg);
reset_screen();
exit(-1);
}
FP_SEG( say_buffer ) = segbuf;
say_buffer += 16; /* set say_buffer ahead of header */
temp_buffer = say_buffer;
for (i=0; i<(BUFFSIZE/BLK); i++) { /* set whole buffer to midline (128) */
for (j=0; j<BLK; j++) {
*(temp_buffer++) = '\x80';
}
}
for (j=0; j<16; j++) {
*(temp_buffer++) = '\x80';
}
block = 0;
section = 0;
quit_flag = FALSE;
while (!quit_flag) {
draw_block(say_buffer);
ret = get_input(&left_cursor, &right_cursor); /* get mouse or kbd input */
switch (ret) {
case F1:
case PLAY: temp_buffer = say_buffer + left_cursor;
size = right_cursor - left_cursor;
say8((void huge *) temp_buffer, size, rate, port_out, treble);
break;
case F2: /* zoom from a pixel per 100 bytes to 1:1. Zoom value could be changed. */
case ZOOM: if (zoom_flag) {
zoom_flag = FALSE;
mpx = 100;
section = 0;
}
else {
zoom_flag = TRUE;
mpx = 1;
section = left_cursor/640; /* start near left cursor position */
}
break;
case F3:
case RECRD: temp_buffer = say_buffer;
for (i=0; i<(BUFFSIZE/64000); i++) { /* clear buffer before recording */
for (j=0; j<64000; j++) {
*(temp_buffer++) = '\x80';
}
}
for (j=0; j<16; j++) {
*(temp_buffer++) = '\x80';
}
get_string("File to record: ", in_fname);
get_string("Rate: ", tmp_num);
rate = atoi(tmp_num);
if (_dos_creat(in_fname, _A_NORMAL, &stream)) {
sprintf(tmp_msg,"Could not open %s", in_fname);
put_error(tmp_msg);
}
get_string("Press <ENTER> to begin recording, then any key to stop");
temp_buffer = say_buffer - 16;
filesize = record8((void huge *) temp_buffer, BUFFSIZE,
rate,0);
if ( kbhit() )
getch(); /* eat char from stopping record routine */
while (filesize > 0) {
if (filesize > 64000)
num_to_write = 64000;
else
num_to_write = filesize;
if (_dos_write(stream, (void far *)temp_buffer, num_to_write, &num_to_write)) {
sprintf(tmp_msg,"Error writing to %s", in_fname);
put_error(tmp_msg);
}
filesize -= num_to_write;
temp_buffer += num_to_write;
}
_dos_close(stream);
break;
case F4:
case LOAD: get_string("File to load: ", in_fname);
if (_dos_open(in_fname, O_RDONLY, &stream)) {
sprintf(tmp_msg,"Could not open %s", in_fname);
put_error(tmp_msg);
}
temp_buffer = say_buffer - 16;
filesize = 0;
for (i=0; i<(BUFFSIZE/64000); i++) {
for (j=0; j<64000; j++)
*(temp_buffer+j) = '\x80'; /* clear each block before data read in */
if (_dos_read(stream, (void far *)temp_buffer, 64000, &num_read)) {
sprintf(tmp_msg,"Error reading %s", in_fname);
put_error(tmp_msg);
}
filesize += num_read;
temp_buffer += 64000;
}
for (j=0; j<16; j++)
*(temp_buffer+j) = '\x80';
tmp_chr = *(say_buffer-7); /* get rate of recording from header */
rate = (int)tmp_chr;
temp_buffer = say_buffer;
_dos_close(stream);
block = 0;
section = 0;
break;
case PGUP: /* go left one section or block */
case L_BUT: if (zoom_flag) {
section--;
if (section < 0) {
if (block == 0) {
section = 0;
}
else {
block--;
section = 99;
}
}
}
else {
block--;
if (block < 0) {
block = 0;
}
}
break;
case PGDN:
case R_BUT: if (zoom_flag) {
section++;
if (section > 99) {
if (block == 3)
section = 99;
else {
block++;
section = 0;
}
}
}
else {
block++;
if (block > 3)
block = 3;
}
break;
case ESC:
case QUIT: quit_flag = TRUE;
break;
} /* end switch */
} /* end main while loop */
fclose(out_fp);
_dos_close(stream);
_dos_freemem(segbuf);
reset_screen();
} /* end main */
/*****************************************************************************
* DRAW_BLOCK
*
* This function draws one full screen of data, either 1:100 or 1:1 depending
* on the value in mpx, which is determined by the state of zoom_flag.
*
*****************************************************************************/
draw_block(char huge *say_buffer)
{
char huge *ptr;
int i;
_setcolor(0);
_rectangle(_GFILLINTERIOR, 0, 20, 639, 299); /* clear display area */
_setcolor(7);
_moveto(0, 147); /* set position to middle point of left margin */
ptr = say_buffer + (block*64000) + (section*640);
for (i=0; i<640; i++) {
plot(i, (BYTE)*ptr);
ptr += mpx;
}
} /* end draw_block */
/****************************************************************************
* INIT_SCREEN
*
* This function set the video mode and draws the basic screen.
*
****************************************************************************/
init_screen()
{
int i;
_setvideomode(_VRES16COLOR);
_remappalette(0, _WHITE);
_remappalette(7, _BLACK);
_settextcolor(7);
_setcolor(7);
_rectangle(_GBORDER, 0, 18, 639, 349);
_moveto(0, 300);
_lineto(639, 300);
for (i=0; i<NUM_BUTTONS; i++)
draw_button(i);
} /* end init_screen */
/****************************************************************************
* RESET_SCREEN
*
* This function restores the video mode active when program started.
*
****************************************************************************/
reset_screen()
{
_setvideomode(_DEFAULTMODE);
} /* end reset_screen */
/****************************************************************************
* GET_INPUT
*
* This function gets either mouse or kbd input and returns either the
* value of the screen button clicked or the ASCII value of the key pushed.
* This routine also sets the left and right cursor, but only by mouse at
* this time. A keyboard equivalent should be added.
*
****************************************************************************/
get_input(long *lc, long *rc)
{
BOOL quit_flag;
int ret, x, y, ch;
long r_curs, l_curs;
char out_str[80];
l_curs = *lc;
r_curs = *rc;
display_m_cursor(SHOW);
quit_flag = FALSE;
while (!quit_flag) {
sprintf(out_str, "Left: %7lu Right: %7lu Block: %d Section: %3d", l_curs, r_curs, block, section);
_settextposition(1, 3);
_outtext(out_str);
/* This peculiar construction is to keep from updating the status line
* every time a check for mouse or key is made. */
if (mse_flag) {
while ( !(ret = check_position(&x, &y)) && (kbhit() == 0) );
}
else {
while (kbhit() == 0);
}
if (ret == RIGHT) {
if (y < 300)
r_curs = (long)(x*mpx) + (long)(block*64000L) + (long)(section*640);
}
else if (ret == LEFT) {
if (y < 300) {
l_curs = (long)(x*mpx) + (long)(block*64000L) + (long)(section*640);
}
else if (y < 350) {
ret = x/WIDTH;
quit_flag = TRUE;
}
}
else {
ch = getch();
if (ch == '\0')
ch = getch();
ret = ch;
quit_flag = TRUE;
}
} /* end while loop */
display_m_cursor(HIDE);
*lc = l_curs;
*rc = r_curs;
return(ret);
} /* end get_input */
/****************************************************************************
* PLOT
*
* This routine simply draws a line from the last point to the current point
*
****************************************************************************/
plot(int ix, BYTE iy)
{
_lineto(ix, (short)(275-iy));
} /* end plot */
/****************************************************************************
* DRAW_BUTTON
*
* This function draws the buttons on the screen.
*
****************************************************************************/
draw_button(int x_pos)
{
display_m_cursor(HIDE);
_settextposition(21, (x_pos*((WIDTH/8)+.5)+3));
_outtext(button_text[x_pos]);
display_m_cursor(SHOW);
} /* end draw_button */
/****************************************************************************
* GET_STRING
*
* This function prints a prompt on the screen under the buttons and gets
* a string back from the user.
*
****************************************************************************/
get_string(char *prompt, char *str)
{
_setcolor(0);
_rectangle(_GFILLINTERIOR, 0, 360, 639, 420);
_setcolor(7);
_settextposition(26, 2);
_outtext(prompt);
gets(str);
} /* end get_string */
/***************************************************************************
* PUT_ERROR
*
* Replacement for fprintf(stderr) in graphics mode. Same as GET_STRING
* but does not return a string.
*
***************************************************************************/
put_error(char *msg)
{
_setcolor(0);
_rectangle(_GFILLINTERIOR, 0, 360, 639, 420);
_setcolor(7);
_settextposition(26, 2);
_outtext(msg);
} /* end put_error */